/**********************************************************************
 * Project : WoWGuildRoster (http://www.codeplex.com/WowGuildRoster/)
 * Module  : DotNetWarcraft.WoWGuildRoster.Business.GuildRosterController
 **********************************************************************
 * 
 * 
 * 
 **********************************************************************
 * License : All code is subject to licensing terms per the Microsoft
 *   Permissive License (Ms-PL) v1.1. For full license information,
 *   refer to the packaged license.txt file.
 **********************************************************************
 * Revision History:
 * -----------------
 * 2009-03-01 -- Cliff Simpkins: v2 code
 **********************************************************************
 */
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

using Microsoft.ApplicationBlocks.Data;
using DotNetWarcraft.WoWGuildRoster.Business.Exceptions;
using DotNetWarcraft.WoWGuildRoster.Data;

namespace DotNetWarcraft.WoWGuildRoster.Business {

  public class GuildRosterController {
    #region Protected Properties - Repository information
    private static Data.IRepository<GuildRoster> _guildRosterRepository;
    private static Data.IRepository<GuildEntry> _guildEntryRepository;
    private static Data.IRepository<GuildEntryStat> _guildEntryStatRepository;
    private static Data.IRepository<WoWGuildRosterException> _exceptionRepository;
    private static Data.IRepository<DataLoad> _dataLoadRepository;

    protected static Data.IRepository<GuildRoster> GuildRosterRepository { 
      get {
        if (_guildRosterRepository == null) {
          SetupRepositoryObjects();
        }
        return _guildRosterRepository;
      } 
    }
    protected static Data.IRepository<GuildEntry> GuildEntryRepository {
      get {
        if (_guildEntryRepository == null) {
          SetupRepositoryObjects();
        }
        return _guildEntryRepository;
      }
    }
    protected static Data.IRepository<GuildEntryStat> GuildEntryStatRepository {
      get {
        if (_guildEntryStatRepository == null) {
          SetupRepositoryObjects();
        }
        return _guildEntryStatRepository;
      }
    }
    protected static Data.IRepository<WoWGuildRosterException> ExceptionRepository {
      get {
        if (_exceptionRepository == null) {
          SetupRepositoryObjects();
        }
        return _exceptionRepository;
      }
    }
    protected static Data.IRepository<DataLoad> DataLoadRepository {
      get {
        if (_dataLoadRepository == null) {
          SetupRepositoryObjects();
        }
        return _dataLoadRepository;
      }
    }

    protected static String ProviderType { get; set; }
    #endregion
    #region Protected Properties - Cached Object Collections
    private static GuildRoster[] _cachedGuildRosters;
    private static GuildEntry[] _cachedGuildEntries;
    protected static GuildRoster[] CachedGuildRosters {
      get {
        if (_cachedGuildRosters == null) {
          LoadCacheObjects();
        }
        return _cachedGuildRosters;
      }
    }
    protected static GuildEntry[] CachedGuildEntries {
      get {
        if (_cachedGuildEntries == null) {
          LoadCacheObjects();
        }
        return _cachedGuildEntries;
      }
    }
    #endregion

    #region Public Methods - Repository information
    public static void SetConnectionString(String connString) {
      ((DataProvider)GuildRosterRepository).ConnectionString = connString;
      ((DataProvider)GuildEntryRepository).ConnectionString = connString;
      ((DataProvider)GuildEntryStatRepository).ConnectionString = connString;
      ((DataProvider)ExceptionRepository).ConnectionString = connString;
      ((DataProvider)DataLoadRepository).ConnectionString = connString;
    }

    public static void SetProvider(String provType) {
      switch (provType.ToLower()) {
        case "sql":
          GuildRosterController.ProviderType = "sql";
          break;
        default:
          return;
      }
    }
    public static void SetObjectQualifier(String objQualifier) {
      if (GuildRosterRepository is SqlDataProvider) {
        ((SqlDataProvider)GuildRosterRepository).ObjectQualifier = objQualifier;
      }
      if (GuildEntryRepository is SqlDataProvider) {
        ((SqlDataProvider)GuildEntryRepository).ObjectQualifier = objQualifier;
      }
      if (GuildEntryStatRepository is SqlDataProvider) {
        ((SqlDataProvider)GuildEntryStatRepository).ObjectQualifier = objQualifier;
      }
      if (ExceptionRepository is SqlDataProvider) {
        ((SqlDataProvider)ExceptionRepository).ObjectQualifier = objQualifier;
      }
      if (DataLoadRepository is SqlDataProvider) {
        ((SqlDataProvider)DataLoadRepository).ObjectQualifier = objQualifier;
      }
    }
    public static void SetDatabaseOwner(String dbOwner) {
      if (GuildRosterRepository is SqlDataProvider) {
        ((SqlDataProvider)GuildRosterRepository).ObjectQualifier = dbOwner;
      }
      if (GuildEntryRepository is SqlDataProvider) {
        ((SqlDataProvider)GuildEntryRepository).ObjectQualifier = dbOwner;
      }
      if (GuildEntryStatRepository is SqlDataProvider) {
        ((SqlDataProvider)GuildEntryStatRepository).ObjectQualifier = dbOwner;
      }
      if (ExceptionRepository is SqlDataProvider) {
        ((SqlDataProvider)ExceptionRepository).ObjectQualifier = dbOwner;
      }
      if (DataLoadRepository is SqlDataProvider) {
        ((SqlDataProvider)DataLoadRepository).ObjectQualifier = dbOwner;
      }
    }
    #endregion
    #region Protected Methods - Repository Information
    protected static void SetupRepositoryObjects() {
      switch (ProviderType.ToLower()) {
        case "sql":
          _guildRosterRepository = new SqlGuildRosteryRepository();
          _guildEntryRepository = new SqlGuildEntryRepository();
          _guildEntryStatRepository = new SqlGuildEntryStatRepository();
          _exceptionRepository = new SqlWgrExceptionRepository();
          _dataLoadRepository = new SqlDataLoadRepository();
          break;
        default:
          return;
      }
    }
    #endregion

    #region Public Methods - Cached Object Collections - Rosters
    public static GuildRoster GetRoster(int rosterId) {
      return CachedGuildRosters.Where(n => n.Roster_ID == rosterId).First();
    }
    public static int AddRoster(GuildRoster objRoster) {
      return GuildRosterRepository.Save(objRoster);
    }
    public static void DeleteRoster(GuildRoster objRoster) {
      GuildRosterRepository.Delete(objRoster);
      return;
    }
    public static void UpdateRoster(GuildRoster objRoster) {
      GuildRosterRepository.Save(objRoster);
      return;
    }

    public static GuildRoster[] GetRosters() {
      return CachedGuildRosters;
    }
    #endregion
    #region Public Methods - Cached Object Collections - Guild Entries
    public static GuildEntry GetGuildEntry(int entryId) {
      return CachedGuildEntries.Where(n => n.Char_ID == entryId).First();
    }
    public static int AddGuildEntry(GuildEntry objGuildEntry) {
      return GuildEntryRepository.Save(objGuildEntry);
    }
    public static void DeleteGuildEntry(GuildEntry objGuildEntry) {
      GuildEntryRepository.Delete(objGuildEntry);
      return;
    }
    public static void UpdateGuildEntry(GuildEntry objGuildEntry) {
      GuildEntryRepository.Save(objGuildEntry);
      return;
    }

    public static GuildEntry[] GetGuildEntries() {
      return CachedGuildEntries;
    }
    public static GuildEntry[] GetGuildEntries(bool showMainsOnly) {
      return CachedGuildEntries.Where(n => n.Primary_Char_Flag > 0).ToArray<GuildEntry>();
    }
    public static GuildEntry[] GetGuildEntries(int rosterId) {
      return CachedGuildEntries.Where(n => n.Roster_ID == rosterId).ToArray<GuildEntry>();
    }
    public static GuildEntry[] GetGuildEntries(int rosterId, bool showMainsOnly) {
      return CachedGuildEntries.Where(n => n.Roster_ID == rosterId && n.Primary_Char_Flag > 0).ToArray<GuildEntry>();
    }



    #endregion
    #region Public Methods - Non-cached Object Collections - Guild Entry Stats
    public static int AddCharStat(GuildEntryStat objRoster) {
      return GuildEntryStatRepository.Save(objRoster);
    }
    public static void DeleteCharStat(GuildEntryStat objCharStat) {
      GuildEntryStatRepository.Delete(objCharStat);
      return;
    }

    public static GuildEntryStat[] GetCharEntryStats() {
      return GuildEntryStatRepository.All();
    }
    public static GuildEntryStat[] GetCharEntryStats(int charId) {
      return ((IGuildEntryStatRepository<GuildEntryStat>)GuildEntryStatRepository).Find_ByChar(charId);
    }
    public static GuildEntryStat[] GetCharEntryStats(String entryName, int statType) {
      return ((IGuildEntryStatRepository<GuildEntryStat>)GuildEntryStatRepository).Find_ByEntryAndType(entryName, statType);
    }
    #endregion

    #region Public Methods - Non-cached Object Collections - Data Loads
    public static DataLoad GetDataLoad(int loadId) {
      return DataLoadRepository.Find(loadId);
    }
    public static int AddDataLoad(DataLoad objDataLoad) {
      return DataLoadRepository.Save(objDataLoad);
    }
    public static void DeleteDataLoad(DataLoad objDataLoad) {
      DataLoadRepository.Delete(objDataLoad);
      return;
    }
    public static int UpdateDataLoad(DataLoad objDataLoad) {
      return DataLoadRepository.Save(objDataLoad);
    }

    public static DataLoad[] GetDataLoads() {
      return DataLoadRepository.All();
    }
    #endregion
    #region Public Methods - Non-cached Object Collections - Exceptions
    public static WoWGuildRosterException GetError(int errorId) {
      return ExceptionRepository.Find(errorId);
    }
    public static int AddError(WoWGuildRosterException objError) {
      return ExceptionRepository.Save(objError);
    }
    public static void DeleteError(WoWGuildRosterException objError) {
      ExceptionRepository.Delete(objError);
      return;
    }

    public static WoWGuildRosterException[] GetErrors() {
      return ExceptionRepository.All();
    }
    #endregion


    #region Protected Methods - Cached Object Collections
    protected static void ClearCacheObjects() {
      _cachedGuildRosters = null;
      _cachedGuildEntries = null;
    }
    protected static void LoadCacheObjects() {
      ClearCacheObjects();
      _cachedGuildRosters = GuildRosterRepository.All();
      _cachedGuildEntries = GuildEntryRepository.All();
    }
    #endregion

  }

  /* Implemented Code
   * 
   *   public class GuildRosterController {
    protected static Data.DataProvider _dbProvider;

    public static Data.DataProvider DbProvider {
      get {
        if (_dbProvider == null) {
          _dbProvider = Data.SqlDataProvider.Instance();
        }

        return _dbProvider;
      }
    }

    public static void SetConnectionString(String connString) {
      DbProvider.ConnectionString = connString;
    }
    public static void SetProviderPath(String provPath) {
      if ((DbProvider) is Data.SqlDataProvider) {
        ((Data.SqlDataProvider)(DbProvider)).ProviderPath = provPath;
      }
    }

   public static void SetObjectQualifier(String objQualifier) {
    if ((DbProvider) is Data.SqlDataProvider) {
      ((Data.SqlDataProvider)(DbProvider)).ObjectQualifier = objQualifier;
    }
  }
  public static void SetDatabaseOwner(String dbOwner) {
    if ((DbProvider) is Data.SqlDataProvider) {
      ((Data.SqlDataProvider)(DbProvider)).DatabaseOwner = dbOwner;
    }
  }
  #region Static Methods - Guild Rosters
  public static List<GuildRoster> GetRosters() {
    //return DbProvider.GetRosters();

    List<GuildRoster> _guilds = new List<GuildRoster>();
    foreach (DataRow _dr in LocalGuildRosters.Rows) {
      GuildRoster _guild = new GuildRoster(_dr);
      _guilds.Add(_guild);
    }
    return _guilds;
  }
  public static GuildRoster GetRoster(int rosterID) {
    //String _funcName = "DotNetWarcraft.WoWGuildRoster.Business.GetRoster(" + rosterID.ToString() + ")";
    //return DbProvider.GetRoster(rosterID);

    return new GuildRoster(LocalGuildRosters.Rows.Find(rosterID));

    //if (_rosters.Length <= 0) {
    //  (new Business.Exceptions.WGRGeneralError(new ApplicationException(_funcName + " - No rosters returned from database"))).WriteExceptionToDB();
    //  return new GuildRoster();
    //} else if (_rosters.Length > 1) {
    //  (new Business.Exceptions.WGRGeneralError(new ApplicationException(_funcName + " - " + _rosters.Length.ToString() + " rows returned from database; only returning first row to application"))).WriteExceptionToDB();
    //  return new GuildRoster(_rosters[0]);
    //} else {
    //  return new GuildRoster(_rosters[0]);
    //}
  }
  public static GuildRoster GetRoster_DB(int rosterID) {
    String _funcName = "DotNetWarcraft.WoWGuildRoster.Business.GetRoster_DB(" + rosterID.ToString() + ")";
    GuildRoster _roster = DbProvider.GetRoster(rosterID);

    return new GuildRoster(LocalGuildRosters.Rows.Find(rosterID));

    //if (_roster == null) {
    //  (new Business.Exceptions.WGRGeneralError(new ApplicationException(_funcName + " - No rosters returned from database"))).WriteExceptionToDB();
    //  return new GuildRoster();
    //} else {
    //  return _roster;
    //}
  }
  public static int AddRoster(GuildRoster objGuildRoster) {
    int _rosterId = ((int)DbProvider.AddRoster(objGuildRoster));
    ForceLocalCacheRefresh();
    return _rosterId;
  }
  public static void UpdateRoster(GuildRoster objGuildRoster) {
    DbProvider.UpdateRoster(objGuildRoster);
    ForceLocalCacheRefresh();
  }
  public static void DeleteRoster(int rosterID) {
    DbProvider.DeleteRoster(rosterID);
    ForceLocalCacheRefresh();
  }

  public static void ProcessEntries_MarkRosterUnprocessed(int RosterID) {
    DbProvider.ProcessGuildEntries_MarkRosterUnprocessed(RosterID);
    DB_ClearLocalData();
  }
  public static void ProcessEntries_MarkPriorUnprocessed(int RosterID, DateTime LoadTimeStart) {
    DbProvider.ProcessGuildEntries_MarkPriorUnprocessed(RosterID, LoadTimeStart);
    DB_ClearLocalData();
  }
  public static void ProcessEntries_MarkPriorUnprocessed(int RosterID, int LoadID) {
    DbProvider.ProcessGuildEntries_MarkPriorUnprocessed(RosterID, LoadID);
    DB_ClearLocalData();
  }
  #endregion

   * 
   */

  /* Ignored code

  #region "Internal Static Methods - Data Cache"
  protected static DataSet _dsLocalGuildRosters;
  protected static bool _doNotClearCacheUponUpdates = false;

  protected static DataSet LocalWgrDataCache {
    get {
      // If the DataSet is null, let's instantiate it
      if (_dsLocalGuildRosters == null) {
        _dsLocalGuildRosters = new DataSet();
      }
      // If the dataset has no tables in it, let's load the data
      if (_dsLocalGuildRosters.Tables.Count <= 0) {
        DB_LoadLocalData();
      }
      return _dsLocalGuildRosters;
    }
    set {
      _dsLocalGuildRosters = value;
    }
  }
  protected static DataTable LocalGuildRosters {
    get {
      return LocalWgrDataCache.Tables[0];
    }
  }
  protected static DataTable LocalGuildCharEntries {
    get {
      return LocalWgrDataCache.Tables[1];
    }
  }
  protected static DataTable LocalGuildRankNames {
    get {
      return LocalWgrDataCache.Tables[2];
    }
  }
  protected static DataTable LocalCharProfessions {
    get {
      return LocalWgrDataCache.Tables[3];
    }
  }
  #endregion
  #region "Internal Static Methods - Database interactions"
  protected static void DB_LoadLocalData() {
    DB_GetRosters();
    DB_LayerPrimaryKeys();
    DB_LayerRelationships();
  }

  public static Boolean ProtectLocalCache {
    get { return _doNotClearCacheUponUpdates; }
    set { _doNotClearCacheUponUpdates = value; }
  }
  public static void ForceLocalCacheRefresh() {
    _dsLocalGuildRosters = null;
  }
  protected static void DB_ClearLocalData() {
    if (!ProtectLocalCache) {
      _dsLocalGuildRosters = null;
    }
  }
  protected static void DB_GetRosters() {
    LocalWgrDataCache = DbProvider.GetRostersDS();
  }
  protected static void DB_LayerPrimaryKeys() {
    LocalGuildRosters.Constraints.Clear();
    LocalGuildRosters.PrimaryKey = new DataColumn[] { LocalGuildRosters.Columns["roster_id"] };
    LocalGuildCharEntries.Constraints.Clear();
    LocalGuildCharEntries.PrimaryKey = new DataColumn[] { LocalGuildCharEntries.Columns["char_id"] };

  }
  protected static void DB_LayerRelationships() {
    if (LocalWgrDataCache.Relations.Contains("RosterCharEntries")) {
      LocalWgrDataCache.Relations.Remove("RosterCharEntries");
    }
    if (!LocalWgrDataCache.Relations.Contains("RosterCharEntries")) {
      DataRelation _rel1 = new DataRelation("RosterCharEntries",
                               LocalGuildRosters.Columns["roster_id"],
                               LocalGuildCharEntries.Columns["roster_id"]);
      try {
        LocalWgrDataCache.Relations.Add(_rel1);
      } catch (Exception) {
      }
    }

    if (LocalWgrDataCache.Relations.Contains("RosterGuildRanks")) {
      LocalWgrDataCache.Relations.Remove("RosterGuildRanks");
    }
    if (!LocalWgrDataCache.Relations.Contains("RosterGuildRanks")) {
      DataRelation _rel2 = new DataRelation("RosterGuildRanks",
                         LocalGuildRosters.Columns["roster_id"],
                         LocalGuildRankNames.Columns["roster_id"]);
      try {
        LocalWgrDataCache.Relations.Add(_rel2);
      } catch (Exception) {
      }
    }

    if (LocalWgrDataCache.Relations.Contains("GuildRankCharEntries")) {
      LocalWgrDataCache.Relations.Remove("GuildRankCharEntries");
    }
    if (!LocalWgrDataCache.Relations.Contains("GuildRankCharEntries")) {
      DataColumn[] _rel3Pcols, _rel3Ccols;
      _rel3Pcols = new DataColumn[] {LocalGuildRankNames.Columns["roster_id"],
                                   LocalGuildRankNames.Columns["guild_rank_value"]};
      _rel3Ccols = new DataColumn[] {LocalGuildCharEntries.Columns["roster_id"],
                                   LocalGuildCharEntries.Columns["game_guild_rank"]};
      DataRelation _rel3 = new DataRelation("GuildRankCharEntries", _rel3Pcols, _rel3Ccols);
      try {
        LocalWgrDataCache.Relations.Add(_rel3);
      } catch (Exception) {
      }
    }

    if (LocalWgrDataCache.Relations.Contains("CharEntryProfessions")) {
      LocalWgrDataCache.Relations.Remove("CharEntryProfessions");
    }
    if (!LocalWgrDataCache.Relations.Contains("CharEntryProfessions")) {
      DataRelation _rel4 = new DataRelation("CharEntryProfessions",
                   LocalGuildCharEntries.Columns["char_id"],
                   LocalCharProfessions.Columns["char_id"]);
      try {
        LocalWgrDataCache.Relations.Add(_rel4);
      } catch (Exception) {
      }

    }

  }
  #endregion

   */
  
  /*
  #region Static Methods - Guild Errors
  public static List<GuildError> GetErrors() {
    return DbProvider.GetErrors();
  }
  public static GuildError GetError(int errorID) {
    return DbProvider.GetError(errorID);
  }

  public static void DeleteErrors() {
    DbProvider.DeleteErrors();
  }
  public static void DeleteErrors(int RosterID) {
    DbProvider.DeleteErrors(RosterID);
  }
  public static void DeleteError(int ErrorID) {
    DbProvider.DeleteError(ErrorID);
  }
  #endregion

  #region Static Methods - Guild Entries
  protected static List<GuildEntry> Helper_ProcessCharEntrys(DataRow[] CharEntries) {
    List<GuildEntry> _entries = new List<GuildEntry>();

    foreach (DataRow _dr in CharEntries) {
      GuildEntry _entry = new GuildEntry(_dr);
      _entries.Add(_entry);
    }
    return _entries;
 }
  protected static List<QuickStatListItem> Helper_ProcessQStatLIs(DataRow[] QuickStatLIs) {
    List<QuickStatListItem> _entries = new List<QuickStatListItem>();

    foreach (DataRow _dr in QuickStatLIs) {
      QuickStatListItem _entry = new QuickStatListItem(_dr);
      _entries.Add(_entry);
    }
    return _entries;
  }

  //Character Entries Return - General by Roster
  public static List<GuildEntry> GetCharEntries() {
    return Helper_ProcessCharEntrys(LocalGuildCharEntries.Select("", "[char_level] DESC, [char_name] ASC"));
  }
  public static List<GuildEntry> GetCharEntries_DB() {
    return DbProvider.GetCharEntries();
  }

  public static List<GuildEntry> GetCharEntries(int RosterID) {
    return GetCharEntries(RosterID, false);
  }
  public static List<GuildEntry> GetCharEntries_DB(int RosterID) {
    return DbProvider.GetCharEntries(RosterID);
  }
  public static List<GuildEntry> GetCharEntries(int RosterID, bool ShowMainsOnly) {
    return GetCharEntries(RosterID, ShowMainsOnly, true);
  }
  public static List<GuildEntry> GetCharEntries(int RosterID, bool ShowMainsOnly, bool ShowCurrentOnly) {

    String _filter = "[roster_id] = " + RosterID.ToString();
    if (ShowMainsOnly) {
      _filter += " AND [primary_char] = 1";
    }
    if (ShowCurrentOnly) {
      _filter += " AND [current_flag] = 1";
    }

    return Helper_ProcessCharEntrys(LocalGuildCharEntries.Select(_filter, "[char_level] DESC, [char_name] ASC"));
  }

  public static List<GuildEntry> GetCharEntriesByLevel(int RosterID, int LevelRange_Min, int LevelRange_Max) {
    return GetCharEntriesByLevel(RosterID, LevelRange_Min, LevelRange_Max, false);
  }
  public static List<GuildEntry> GetCharEntriesByLevel(int RosterID, int LevelRange_Min, int LevelRange_Max, bool ShowMainsOnly) {
    return GetCharEntriesByLevel(RosterID, LevelRange_Min, LevelRange_Max, ShowMainsOnly, true);
  }
  public static List<GuildEntry> GetCharEntriesByLevel(int RosterID, int LevelRange_Min, int LevelRange_Max, bool ShowMainsOnly, bool ShowCurrentOnly) {
    //return DbProvider.GetCharEntries(RosterID, LevelRange_Min, LevelRange_Max);

    String _filter = "[roster_id] = " + RosterID.ToString() + " AND [char_level] >= " + LevelRange_Min.ToString() + " AND [char_level] <= " + LevelRange_Max.ToString();
    if (ShowMainsOnly) {
      _filter += " AND [primary_char] = 1";
    }
    if (ShowCurrentOnly) {
      _filter += " AND [current_flag] = 1";
    }

    return Helper_ProcessCharEntrys(LocalGuildCharEntries.Select(_filter, "[char_level] DESC, [char_name] ASC"));
  }

  public static List<GuildEntry> GetCharEntriesByClass(int RosterID, String ClassName) {
    return GetCharEntriesByClass(RosterID, ClassName, 1, 9999);
  }
  public static List<GuildEntry> GetCharEntriesByClass(int RosterID, String ClassName, int LevelRange_Min, int LevelRange_Max) {
    return GetCharEntriesByClass(RosterID, ClassName, LevelRange_Min, LevelRange_Max, false);
  }
  public static List<GuildEntry> GetCharEntriesByClass(int RosterID, String ClassName, int LevelRange_Min, int LevelRange_Max, bool ShowMainsOnly) {
    return GetCharEntriesByClass(RosterID, ClassName, LevelRange_Min, LevelRange_Max, ShowMainsOnly, true);
  }
  public static List<GuildEntry> GetCharEntriesByClass(int RosterID, String ClassName, int LevelRange_Min, int LevelRange_Max, bool ShowMainsOnly, bool ShowCurrentOnly) {
    String _filter = "[roster_id] = " + RosterID.ToString() + " AND [char_class] = '" + ClassName + "' AND [char_level] >= " + LevelRange_Min.ToString() + " AND [char_level] <= " + LevelRange_Max.ToString();
    if (ShowMainsOnly) {
      _filter += " AND [primary_char] = 1";
    }
    if (ShowCurrentOnly) {
      _filter += " AND [current_flag] = 1";
    }

    return Helper_ProcessCharEntrys(LocalGuildCharEntries.Select(_filter, "[char_level] DESC, [char_name] ASC"));
  }

  public static List<QuickStatListItem> GetCharEntriesByProf(int RosterID, String ProfName) {
    return GetCharEntriesByProf(RosterID, ProfName, false);
  }
  public static List<QuickStatListItem> GetCharEntriesByProf(int RosterID, String ProfName, bool ShowMainsOnly) {
    return GetCharEntriesByProf(RosterID, ProfName, ShowMainsOnly, true);
  }
  public static List<QuickStatListItem> GetCharEntriesByProf(int RosterID, String ProfName, bool ShowMainsOnly, bool ShowCurrentOnly) {
    String _filter = "[roster_id] = " + RosterID.ToString() + " AND [stat_entry] = '" + ProfName + "'";
    if (ShowMainsOnly) {
      _filter += " AND [primary_char] = 1";
    }
    if (ShowCurrentOnly) {
      _filter += " AND [current_flag] = 1";
    }
    return Helper_ProcessQStatLIs(LocalCharProfessions.Select(_filter, "[stat_value_int] DESC, [char_name] ASC"));
  }

  public static List<GuildEntry> GetCharEntriesByGuildRank(int RosterID, int GuildRank) {
    return GetCharEntriesByGuildRank(RosterID, GuildRank, false);
  }
  public static List<GuildEntry> GetCharEntriesByGuildRank(int RosterID, int GuildRank, bool ShowMainsOnly) {
    return GetCharEntriesByGuildRank(RosterID, GuildRank, ShowMainsOnly, true);
  }
  public static List<GuildEntry> GetCharEntriesByGuildRank(int RosterID, int GuildRank, bool ShowMainsOnly, bool ShowCurrentOnly) {
    String _filter = "[roster_id] = " + RosterID.ToString() + " AND [guild_rank_value] = " + GuildRank.ToString();
    String _sort = "[guild_rank_value] DESC";

    String _filter2 = "[roster_id] = " + RosterID.ToString() + " AND [game_guild_rank] = " + GuildRank.ToString();
    String _sort2 = "[char_level] DESC, [char_name] ASC";
    if (ShowMainsOnly) {
      _filter2 += " AND [primary_char] = 1";
    }
    if (ShowCurrentOnly) {
      _filter2 += " AND [current_flag] = 1";
    }

    List<GuildEntry> _entries = new List<GuildEntry>();

    DataTable _rank = LocalGuildCharEntries.Clone();

    foreach (DataRow _guildRank in (LocalGuildRankNames.Select(_filter, _sort))) {
      DataRow[] _relatedRows;
      _relatedRows = _guildRank.GetChildRows("GuildRankCharEntries");
      //_rank.Rows.InsertAt(_relatedRows, _rank.Rows.Count + 1);

      foreach (DataRow _dr in _guildRank.GetChildRows("GuildRankCharEntries")) {
        _rank.ImportRow(_dr);
      }
    }

    return Helper_ProcessCharEntrys(_rank.Select(_filter2, _sort2));
  }

    
  public static List<GuildEntry> GetCharEntries_Alts(int mainCharID) {
    //return DbProvider.GetCharEntries_Alts(mainCharID);

    return Helper_ProcessCharEntrys(LocalGuildCharEntries.Select(
      "alt_to_main = " + mainCharID.ToString(),
      "char_level DESC, char_name"));
  }

  public static GuildEntry GetCharEntry(int entryID) {
    //return DbProvider.GetCharEntry(entryID);

    return new GuildEntry(LocalGuildCharEntries.Rows.Find(entryID));

  }
  public static GuildEntry GetCharEntry_DB(int entryID) {
    return DbProvider.GetCharEntry(entryID);
  }
  public static GuildEntry GetCharEntry(String charName, String serverName) {
    //return DbProvider.GetCharEntry(charName, serverName);
    String _funcName = "DotNetWarcraft.WoWGuildRoster.Business.GetCharEntry(" + charName + ", " + serverName + ")";


    String _filter = "[char_name] = '" + charName + "' AND [char_server] = '" + serverName.Replace("'", "''") + "'";

    DataRow[] _chars = LocalGuildCharEntries.Select(_filter, "[char_name] ASC");

    if (_chars.Length <= 0) {
      // Commenting out the error, since it's not BAD if it's a new character. :)
      // (new Business.Exceptions.WGRGeneralError(new ApplicationException(_funcName + " - No char entries returned from database"))).WriteExceptionToDB();
      return new GuildEntry();
    } else if (_chars.Length > 1) {
      for (int __i = 1; __i < _chars.Length; __i++) {
        GuildEntry __charToDel = new GuildEntry(_chars[__i]);
        if (__charToDel.Char_ID >= 0) {
          DeleteCharEntry(__charToDel.Char_ID);
        }
      }
      (new Business.Exceptions.WGRGeneralError(new ApplicationException(_funcName + " - WARNING - " + _chars.Length.ToString() + " rows returned from database; only returning first row to application and removed duplicates"))).WriteExceptionToDB();

      return new GuildEntry(_chars[0]);
    } else {
      return new GuildEntry(_chars[0]);
    }

  }
  public static GuildEntry GetCharEntry_DB(String charName, String serverName) {
    return DbProvider.GetCharEntry(charName, serverName);
  }
  public static GuildEntry GetCharEntry_NextValid(int lastProcessedCharID) {
    //return DbProvider.GetCharEntry(charName, serverName);
    String _funcName = "DotNetWarcraft.WoWGuildRoster.Business.GetCharEntry_GetCharEntry_NextValid(" + lastProcessedCharID.ToString() + ")";


    String _filter = "[char_id] > " + lastProcessedCharID.ToString() + " AND [current_flag] = 1";

    DataRow[] _chars = LocalGuildCharEntries.Select(_filter, "[char_id]");

    if (_chars.Length <= 0) {
      // Commenting out the error, since it's not BAD if it's a new character. :)
      // (new Business.Exceptions.WGRGeneralError(new ApplicationException(_funcName + " - No char entries returned from database"))).WriteExceptionToDB();
      return new GuildEntry();
    } else {
      return new GuildEntry(_chars[0]);
    }

  }
  public static int AddCharEntry(GuildEntry objGuildEntry) {
    objGuildEntry.Char_ID = ((int)DbProvider.AddCharEntry(objGuildEntry));
    ForceLocalCacheRefresh();
    return objGuildEntry.Char_ID;
  }
  public static void UpdateCharEntry(GuildEntry objGuildEntry) {
    DbProvider.UpdateCharEntry(objGuildEntry);
    DB_ClearLocalData();
  }
  public static void DeleteCharEntry(int entryID) {
    DbProvider.DeleteCharEntry(entryID);
    DB_ClearLocalData();
  }
  #endregion

  #region Static Methods - Guild Entry Stats
  public static List<GuildEntryStat> GetCharEntryStats() {
    return DbProvider.GetCharEntryStats();
  }
  public static List<GuildEntryStat> GetCharEntryStats_ByCharEntry(int entryID) {
    return DbProvider.GetCharEntryStats_ByCharEntry(entryID);
  }
  public static List<GuildEntryStat> GetCharEntryStats_ByCharAndType(int entryID, int statTypeID) {
    return DbProvider.GetCharEntryStats_ByCharEntryAndType(entryID, statTypeID);
  }
  public static List<GuildEntryStat> GetCharEntryStats_ByCharAndType(int entryID, WarcraftStatTypes statTypeEnum) {
    return DbProvider.GetCharEntryStats_ByCharEntryAndType(entryID, statTypeEnum);
  }
  public static List<GuildEntryStat> GetCharEntryStats_ByCharAndTypeAndGroup(int entryID, int statTypeID, String statGroup) {
    return DbProvider.GetCharEntryStats_ByCharEntryAndTypeAndGroup(entryID, statTypeID, statGroup);
  }
  public static List<GuildEntryStat> GetCharEntryStats_ByCharAndTypeAndGroup(int entryID, WarcraftStatTypes statTypeEnum, String statGroup) {
    return DbProvider.GetCharEntryStats_ByCharEntryAndTypeAndGroup(entryID, statTypeEnum, statGroup);
  }
  public static GuildEntryStat GetCharEntryStat(int entryStatID) {
    return DbProvider.GetCharEntryStat(entryStatID);
  }
  public static GuildEntryStat GetCharEntryStat(int entryID, int statType, String statGroup, String statEntry) {
    return DbProvider.GetCharEntryStat(entryID, statType, statGroup, statEntry);
  }
  public static int AddCharEntryStat(GuildEntryStat objGuildEntry) {
    return ((int)DbProvider.AddUpdateCharEntryStat(objGuildEntry));
  }
  public static void UpdateCharEntryStat(GuildEntryStat objGuildEntryStat) {
    DbProvider.AddUpdateCharEntryStat(objGuildEntryStat);
  }
  public static void DeleteCharEntryStat(int entryStatID) {
    DbProvider.DeleteCharEntryStat(entryStatID);
  }
  public static void DeleteCharEntryStats_ByCharEntry(int entryID) {
    DbProvider.DeleteCharEntryStats_ByChar(entryID);
    }
  public static void DeleteCharEntryStats_ByCharEntry(int entryID, WarcraftStatTypes statTypeEnum) {
    DbProvider.DeleteCharEntryStats_ByChar(entryID, statTypeEnum);
    }

  public static List<QuickStatListItem> GetEntryStatsLIs_ByGuildRank(int guildRank, bool mainsOnly) {
    return DbProvider.GetEntryStatsLIs_ByGuildRank(guildRank, mainsOnly);
  }
  public static List<QuickStatListItem> GetEntryStatsLIs_ByStatEntryAndType(String statEntry, WarcraftStatTypes statTypeEnum, bool mainsOnly) {
    return DbProvider.GetEntryStatsLIs_ByStatEntryAndType(statEntry, statTypeEnum, mainsOnly);
  }
  public static List<QuickStatListItem> GetEntryStatsLIs_ByStatEntryAndType(String statEntry, int statTypeID, bool mainsOnly) {
    return DbProvider.GetEntryStatsLIs_ByStatEntryAndType(statEntry, statTypeID, mainsOnly);
  }
  public static List<QuickStatListItem> GetEntryStatsLIs_ByStatEntryAndTypeAndGroup(String statEntry, String statGroup, WarcraftStatTypes statTypeEnum, bool mainsOnly) {
    return DbProvider.GetEntryStatsLIs_ByStatEntryAndTypeAndGroup(statEntry, statGroup, statTypeEnum, mainsOnly);
  }
  public static List<QuickStatListItem> GetEntryStatsLIs_ByStatEntryAndTypeAndGroup(String statEntry, String statGroup, int statTypeID, bool mainsOnly) {
    return DbProvider.GetEntryStatsLIs_ByStatEntryAndTypeAndGroup(statEntry, statGroup, statTypeID, mainsOnly);
  }

  #endregion

  #region Static Methods - Drop-Down Values
  public static List<String> GetDropDown_Classes() {
    return DbProvider.GetDropDowns_CharClasses();
  }
  public static List<String> GetDropDown_Professions() {
    return DbProvider.GetDropDowns_CharProfessions();
  }
  public static List<String> GetDropDown_Reputations() {
    return DbProvider.GetDropDowns_Reputations();
  }

  public static List<String> GetDropDown_ReputationGroups(int charID) {
    return DbProvider.GetDropDowns_ReputationGroups(charID);
  }

  #endregion
}
   */
  /* Also implemented
   *   #region Static Methods - Data Loads
  public static List<DataLoad> GetDataLoads() {
    return DbProvider.GetDataLoads();
  }
  public static DataLoad GetDataLoad(int loadID) {
    return DbProvider.GetDataLoad(loadID);
  }
  public static DataLoad GetDataLoad_CurrentCharLoad() {
    return DbProvider.GetDataLoad_CurrentCharLoad();
  }
  public static int AddDataLoad(DataLoad objDataLoad) {
    return ((int)DbProvider.AddDataLoad(objDataLoad));
  }
  public static void UpdateDataLoad(DataLoad objDataLoad) {
    DbProvider.UpdateDataLoad(objDataLoad);
  }
  public static void DeleteDataLoads() {
    DbProvider.DeleteDataLoads();
  }
  public static void DeleteDataLoad(int loadID) {
    DbProvider.DeleteDataLoad(loadID);
  }
  #endregion

  */
}
